import router from '@/router';
import { useUserStoreHook } from '@/store/modules/user';
import { usePermissionStoreHook } from '@/store/modules/permission';
import { ElMessage } from 'element-plus';
import { setRouteChange } from '@/hooks/useRouteListener';
import { useTitle } from '@/hooks/useTitle';
import { getToken } from '@/utils/cache/cookies';
import routeSettings from '@/config/route';
import isWhiteList from '@/config/white-list';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';

const { setTitle } = useTitle();
NProgress.configure({ showSpinner: false });

router.beforeEach(async (to, _from, next) => {
	// ? 未登录 { 白名单放行 / 跳转到登录页 }
	// ? 已登录 不能跳回登录页
	// ? 如果已经登录，那么还要检查是否拿到用户角色，如果没有，则要调用用户详情接口
	// ? 如果开启了动态路由功能，就根据角色去过滤动态路由；如果没有开启动态路由功能，则生成所有路由

	NProgress.start();
	const userStore = useUserStoreHook();
	const permissionStore = usePermissionStoreHook();
	const token = getToken();

	// 如果没有登陆
	if (!token) {
		// 如果在免登录的白名单中，则直接进入
		if (isWhiteList(to)) return next();
		// 其他没有访问权限的页面将被重定向到登录页面
		return next('/login');
	}

	// 如果已经登录，并准备进入 Login 页面，则重定向到主页
	if (to.path === '/login') {
		return next({ path: '/' });
	}

	// 如果用户已经获得其权限角色
	if (userStore.roles.length !== 0) return next();

	// 否则要重新获取权限角色
	try {
		await userStore.getInfo();
		// 注意：角色必须是一个数组！ 例如: ["admin"] 或 ["developer", "editor"]
		const roles = userStore.roles;
		// 生成可访问的 Routes
		// 是否开启动态路由功能 开启后，静态路由 + 有权限的路由  关闭后，静态路由 + 动态路由
		routeSettings.dynamic ? permissionStore.setRoutes(roles) : permissionStore.setAllRoutes();
		// 将 "有访问权限的动态路由" 添加到 Router 中
		permissionStore.addRoutes.forEach((route) => router.addRoute(route));
		// 确保添加路由已完成
		// 设置 replace: true, 因此导航将不会留下历史记录
		next({ ...to, replace: true });
	} catch (err: any) {
		// 过程中发生任何错误，都直接重置 Token，并重定向到登录页面
		userStore.resetToken();
		ElMessage.error(err.message || '路由守卫过程发生错误');
		next('/login');
	}
});

router.afterEach((to) => {
	setRouteChange(to);
	setTitle(to.meta.title);
	NProgress.done();
});
